home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / cpu / pdp1 / pdp1.c next >
Text File  |  2000-04-23  |  31KB  |  983 lines

  1. /*
  2.  * Note: Original Java source written by:
  3.  *
  4.  * Barry Silverman mailto:barry@disus.com or mailto:bss@media.mit.edu
  5.  * Vadim Gerasimov mailto:vadim@media.mit.edu
  6.  * (not much was changed, only the IOT stuff and the 64 bit integer shifts)
  7.  *
  8.  * Note: I removed the IOT function to be external, it is
  9.  * set at emulation initiation, the IOT function is part of
  10.  * the machine emulation...
  11.  *
  12.  *
  13.  * for the runnable java applet go to:
  14.  * http://lcs.www.media.mit.edu/groups/el/projects/spacewar/
  15.  *
  16.  * for a complete html version of the pdp1 handbook go to:
  17.  * http://www.dbit.com/~greeng3/pdp1/index.html
  18.  *
  19.  * there is another java simulator (by the same people) which runs the
  20.  * original pdp1 LISP interpreter, go to:
  21.  * http://lcs.www.media.mit.edu/groups/el/projects/pdp1
  22.  *
  23.  * and finally, there is a nice article about SPACEWAR!, go to:
  24.  * http://ars-www.uchicago.edu/~eric/lore/spacewar/spacewar.html
  25.  *
  26.  * following is an extract from the handbook:
  27.  *
  28.  * INTRODUCTION
  29.  *
  30.  * The Programmed Data Processor (PDP-1) is a high speed, solid state digital computer designed to
  31.  * operate with many types of input-output devices with no internal machine changes. It is a single
  32.  * address, single instruction, stored program computer with powerful program features. Five-megacycle
  33.  * circuits, a magnetic core memory and fully parallel processing make possible a computation rate of
  34.  * 100,000 additions per second. The PDP-1 is unusually versatile. It is easy to install, operate and
  35.  * maintain. Conventional 110-volt power is used, neither air conditioning nor floor reinforcement is
  36.  * necessary, and preventive maintenance is provided for by built-in marginal checking circuits.
  37.  *
  38.  * PDP-1 circuits are based on the designs of DEC's highly successful and reliable System Modules.
  39.  * Flip-flops and most switches use saturating transistors. Primary active elements are
  40.  * Micro-Alloy-Diffused transistors.
  41.  *
  42.  * The entire computer occupies only 17 square feet of floor space. It consists of four equipment frames,
  43.  * one of which is used as the operating station.
  44.  *
  45.  * CENTRAL PROCESSOR
  46.  *
  47.  * The Central Processor contains the control, arithmetic and memory addressing elements, and the memory
  48.  * buffer register. The word length is 18 binary digits. Instructions are performed in multiples of the
  49.  * memory cycle time of five microseconds. Add, subtract, deposit, and load, for example, are two-cycle
  50.  * instructions requiring 10 microseconds. Multiplication requires and average of 20 microseconds.
  51.  * Program features include: single address instructions, multiple step indirect addressing and logical
  52.  * arithmetic commands. Console features include: flip-flop indicators grouped for convenient octal
  53.  * reading, six program flags for automatic setting and computer sensing, and six sense switches for
  54.  * manual setting and computer sensing.
  55.  *
  56.  * MEMORY SYSTEM
  57.  *
  58.  * The coincident-current, magnetic core memory of a standard PDP-1 holds 4096 words of 18 bits each.
  59.  * Memory capacity may be readily expanded, in increments of 4096 words, to a maximum of 65,536 words.
  60.  * The read-rewrite time of the memory is five microseconds, the basic computer rate. Driving currents
  61.  * are automatically adjusted to compensate for temperature variations between 50 and 110 degrees
  62.  * Fahrenheit. The core memory storage may be supplemented by up to 24 magnetic tape transports.
  63.  *
  64.  * INPUT-OUTPUT
  65.  *
  66.  * PDP-1 is designed to operate a variety of buffered input-output devices. Standard equipment consistes
  67.  * of a perforated tape reader with a read speed of 400 lines per second, and alphanuermic typewriter for
  68.  * on-line operation in both input and output, and a perforated tape punch (alphanumeric or binary) with
  69.  * a speed of 63 lines per second. A variety of optional equipment is available, including the following:
  70.  *
  71.  *     Precision CRT Display Type 30
  72.  *     Ultra-Precision CRT Display Type 31
  73.  *     Symbol Generator Type 33
  74.  *     Light Pen Type 32
  75.  *     Oscilloscope Display Type 34
  76.  *     Card Punch Control Type 40-1
  77.  *     Card Reader and Control Type 421
  78.  *     Magnetic Tape Transport Type 50
  79.  *     Programmed Magnetic Tape Control Type 51
  80.  *     Automatic Magnetic Tape Control Type 52
  81.  *     Automatic Magnetic Tape Control Type 510
  82.  *     Parallel Drum Type 23
  83.  *     Automatic Line Printer and Control Type 64
  84.  *     18-bit Real Time Clock
  85.  *     18-bit Output Relay Buffer Type 140
  86.  *     Multiplexed A-D Converter Type 138/139
  87.  *
  88.  * All in-out operations are performed through the In-Out Register or through the high speed input-output
  89.  * channels.
  90.  *
  91.  * The PDP-1 is also available with the optional Sequence Break System. This is a multi-channel priority
  92.  * interrupt feature which permits concurrent operation of several in-out devices. A one-channel Sequence
  93.  * Break System is included in the standard PDP-1. Optional Sequence Break Systems consist of 16, 32, 64,
  94.  * 128, and 256 channels.
  95.  *
  96.  * ...
  97.  *
  98.  * BASIC INSTRUCTIONS
  99.  *
  100.  *                                                                    OPER. TIME
  101.  * INSTRUCTION  CODE #  EXPLANATION                                     (usec)
  102.  * ------------------------------------------------------------------------------
  103.  * add Y        40      Add C(Y) to C(AC)                                 10
  104.  * and Y        02      Logical AND C(Y) with C(AC)                       10
  105.  * cal Y        16      Equals jda 100                                    10
  106.  * dac Y        24      Deposit C(AC) in Y                                10
  107.  * dap Y        26      Deposit contents of address part of AC in Y       10
  108.  * dio Y        32      Deposit C(IO) in Y                                10
  109.  * dip Y        30      Deposit contents of instruction part of AC in Y   10
  110.  * div Y        56      Divide                                          40 max
  111.  * dzm Y        34      Deposit zero in Y                                 10
  112.  * idx Y        44      Index (add one) C(Y), leave in Y & AC             10
  113.  * ior Y        04      Inclusive OR C(Y) with C(AC)                      10
  114.  * iot Y        72      In-out transfer, see below
  115.  * isp Y        46      Index and skip if result is positive              10
  116.  * jda Y        17      Equals dac Y and jsp Y+1                          10
  117.  * jmp Y        60      Take next instruction from Y                      5
  118.  * jsp Y        62      Jump to Y and save program counter in AC          5
  119.  * lac Y        20      Load the AC with C(Y)                             10
  120.  * law N        70      Load the AC with the number N                     5
  121.  * law-N        71      Load the AC with the number -N                    5
  122.  * lio Y        22      Load IO with C(Y)                                 10
  123.  * mul Y        54      Multiply                                        25 max
  124.  * opr          76      Operate, see below                                5
  125.  * sad Y        50      Skip next instruction if C(AC) <> C(Y)            10
  126.  * sas Y        52      Skip next instruction if C(AC) = C(Y)             10
  127.  * sft          66      Shift, see below                                  5
  128.  * skp          64      Skip, see below                                   5
  129.  * sub Y        42      Subtract C(Y) from C(AC)                          10
  130.  * xct Y        10      Execute instruction in Y                          5+
  131.  * xor Y        06      Exclusive OR C(Y) with C(AC)                      10
  132.  *
  133.  * OPERATE GROUP
  134.  *
  135.  *                                                                    OPER. TIME
  136.  * INSTRUCTION  CODE #   EXPLANATION                                    (usec)
  137.  * ------------------------------------------------------------------------------
  138.  * cla        760200     Clear AC                                         5
  139.  * clf        76000f     Clear selected Program Flag (f = flag #)         5
  140.  * cli        764000     Clear IO                                         5
  141.  * cma        761000     Complement AC                                    5
  142.  * hlt        760400     Halt                                             5
  143.  * lap        760100     Load AC with Program Counter                     5
  144.  * lat        762200     Load AC from Test Word switches                  5
  145.  * nop        760000     No operation                                     5
  146.  * stf        76001f     Set selected Program Flag                        5
  147.  *
  148.  * IN-OUT TRANSFER GROUP
  149.  *
  150.  * PERFORATED TAPE READER
  151.  *
  152.  * INSTRUCTION  CODE #   EXPLANATION
  153.  * ------------------------------------------------------------------------------
  154.  * rpa        720001     Read Perforated Tape Alphanumeric
  155.  * rpb        720002     Read Perforated Tape Binary
  156.  * rrb        720030     Read Reader Buffer
  157.  *
  158.  * PERFORATED TAPE PUNCH
  159.  *
  160.  * INSTRUCTION  CODE #   EXPLANATION
  161.  * ------------------------------------------------------------------------------
  162.  * ppa        720005     Punch Perforated Tape Alphanumeric
  163.  * ppb        720006     Punch Perforated Tape Binary
  164.  *
  165.  * ALPHANUMERIC ON-LINE TYPEWRITER
  166.  *
  167.  * INSTRUCTION  CODE #   EXPLANATION
  168.  * ------------------------------------------------------------------------------
  169.  * tyo        720003     Type Out
  170.  * tyi        720004     Type In
  171.  *
  172.  * SEQUENCE BREAK SYSTEM TYPE 120
  173.  *
  174.  * INSTRUCTION  CODE #   EXPLANATION
  175.  * ------------------------------------------------------------------------------
  176.  * esm        720055     Enter Sequence Break Mode
  177.  * lsm        720054     Leave Sequence Break Mode
  178.  * cbs        720056     Clear Sequence Break System
  179.  * dsc        72kn50     Deactivate Sequence Break Channel
  180.  * asc        72kn51     Activate Sequence Break Channel
  181.  * isb        72kn52     Initiate Sequence Break
  182.  * cac        720053     Clear All Channels
  183.  *
  184.  * HIGH SPEED DATA CONTROL TYPE 131
  185.  *
  186.  * INSTRUCTION  CODE #   EXPLANATION
  187.  * ------------------------------------------------------------------------------
  188.  * swc        72x046     Set Word Counter
  189.  * sia        720346     Set Location Counter
  190.  * sdf        720146     Stop Data Flow
  191.  * rlc        720366     Read Location Counter
  192.  * shr        720446     Set High Speed Channel Request
  193.  *
  194.  * PRECISION CRT DISPLAY TYPE 30
  195.  *
  196.  * INSTRUCTION  CODE #   EXPLANATION
  197.  * ------------------------------------------------------------------------------
  198.  * dpy        720007     Display One Point
  199.  *
  200.  * SYMBOL GENERATOR TYPE 33
  201.  *
  202.  * INSTRUCTION  CODE #   EXPLANATION
  203.  * ------------------------------------------------------------------------------
  204.  * gpl        722027     Generator Plot Left
  205.  * gpr        720027     Generator Plot Right
  206.  * glf        722026     Load Format
  207.  * gsp        720026     Space
  208.  * sdb        722007     Load Buffer, No Intensity
  209.  *
  210.  * ULTRA-PRECISION CRT DISPLAY TYPE 31
  211.  *
  212.  * INSTRUCTION  CODE #   EXPLANATION
  213.  * ------------------------------------------------------------------------------
  214.  * dpp        720407     Display One Point on Ultra Precision CRT
  215.  *
  216.  * CARD PUNCH CONTROL TYPE 40-1
  217.  *
  218.  * INSTRUCTION  CODE #   EXPLANATION
  219.  * ------------------------------------------------------------------------------
  220.  * lag        720044     Load a Group
  221.  * pac        720043     Punch a Card
  222.  *
  223.  * CARD READER TYPE 421
  224.  *
  225.  * INSTRUCTION  CODE #   EXPLANATION
  226.  * ------------------------------------------------------------------------------
  227.  * rac        720041     Read Card Alpha
  228.  * rbc        720042     Read Card Binary
  229.  * rcc        720032     Read Card Column
  230.  *
  231.  * PROGRAMMED MAGNETIC TAPE CONTROL TYPE 51
  232.  *
  233.  * INSTRUCTION  CODE #   EXPLANATION
  234.  * ------------------------------------------------------------------------------
  235.  * msm        720073     Select Mode
  236.  * mcs        720034     Check Status
  237.  * mcb        720070     Clear Buffer
  238.  * mwc        720071     Write a Character
  239.  * mrc        720072     Read Character
  240.  *
  241.  * AUTOMATIC MAGNETIC TAPE CONTROL TYPE 52
  242.  *
  243.  * INSTRUCTION  CODE #   EXPLANATION
  244.  * ------------------------------------------------------------------------------
  245.  * muf        72ue76     Tape Unit and FinalT
  246.  * mic        72ue75     Initial and Command
  247.  * mrf        72u067     Reset Final
  248.  * mri        72ug66     Reset Initial
  249.  * mes        72u035     Examine States
  250.  * mel        72u036     Examine Location
  251.  * inr        72ur67     Initiate a High Speed Channel Request
  252.  * ccr        72s067     Clear Command Register
  253.  *
  254.  * AUTOMATIC MAGNETIC TAPE CONTROL TYPE 510
  255.  *
  256.  * INSTRUCTION  CODE #   EXPLANATION
  257.  * ------------------------------------------------------------------------------
  258.  * sfc        720072     Skip if Tape Control Free
  259.  * rsr        720172     Read State Register
  260.  * crf        720272     Clear End-of-Record Flip-Flop
  261.  * cpm        720472     Clear Proceed Mode
  262.  * dur        72xx70     Load Density, Unit, Rewind
  263.  * mtf        73xx71     Load Tape Function Register
  264.  * cgo        720073     Clear Go
  265.  *
  266.  * MULTIPLEXED A-D CONVERTER TYPE 138/139
  267.  *
  268.  * INSTRUCTION  CODE #   EXPLANATION
  269.  * ------------------------------------------------------------------------------
  270.  * rcb        720031     Read Converter Buffer
  271.  * cad        720040     Convert a Voltage
  272.  * scv        72mm47     Select Multiplexer (1 of 64 Channels)
  273.  * icv        720060     Index Multiplexer
  274.  *
  275.  * AUTOMATIC LINE PRINTER TYPE 64
  276.  *
  277.  * INSTRUCTION  CODE #   EXPLANATION
  278.  * ------------------------------------------------------------------------------
  279.  * clrbuf     722045     Clear Buffer
  280.  * lpb        720045     Load Printer Buffer
  281.  * pas        721x45     Print and Space
  282.  *
  283.  * SKIP GROUP
  284.  *
  285.  *                                                                    OPER. TIME
  286.  * INSTRUCTION  CODE #   EXPLANATION                                    (usec)
  287.  * ------------------------------------------------------------------------------
  288.  * sma        640400     Dkip on minus AC                                 5
  289.  * spa        640200     Skip on plus AC                                  5
  290.  * spi        642000     Skip on plus IO                                  5
  291.  * sza        640100     Skip on ZERO (+0) AC                             5
  292.  * szf        6400f      Skip on ZERO flag                                5
  293.  * szo        641000     Skip on ZERO overflow (and clear overflow)       5
  294.  * szs        6400s0     Skip on ZERO sense switch                        5
  295.  *
  296.  * SHIFT/ROTATE GROUP
  297.  *
  298.  *                                                                      OPER. TIME
  299.  * INSTRUCTION  CODE #   EXPLANATION                                      (usec)
  300.  * ------------------------------------------------------------------------------
  301.  *   ral        661      Rotate AC left                                     5
  302.  *   rar        671      Rotate AC right                                    5
  303.  *   rcl        663      Rotate Combined AC & IO left                       5
  304.  *   rcr        673      Rotate Combined AC & IO right                      5
  305.  *   ril        662      Rotate IO left                                     5
  306.  *   rir        672      Rotate IO right                                    5
  307.  *   sal        665      Shift AC left                                      5
  308.  *   sar        675      Shift AC right                                     5
  309.  *   scl        667      Shift Combined AC & IO left                        5
  310.  *   scr        677      Shift Combined AC & IO right                       5
  311.  *   sil        666      Shift IO left                                      5
  312.  *   sir        676      Shift IO right                                     5
  313.  */
  314.  
  315. #include <stdio.h>
  316. #include <stdlib.h>
  317. #include "driver.h"
  318. #include "mamedbg.h"
  319. #include "pdp1.h"
  320.  
  321. #define READ_PDP_18BIT(A) ((signed)cpu_readmem16(A))
  322. #define WRITE_PDP_18BIT(A,V) (cpu_writemem16(A,V))
  323.  
  324. /* Layout of the registers in the debugger */
  325. static UINT8 pdp1_reg_layout[] =
  326. {
  327.     PDP1_PC, PDP1_AC, PDP1_IO, PDP1_Y, PDP1_IB, PDP1_OV, PDP1_F, -1,
  328.     PDP1_F1, PDP1_F2, PDP1_F3, PDP1_F4, PDP1_F5, PDP1_F6, -1,
  329.     PDP1_S1, PDP1_S2, PDP1_S3, PDP1_S4, PDP1_S5, PDP1_S6, 0
  330. };
  331.  
  332. /* Layout of the debugger windows x,y,w,h */
  333. static UINT8 pdp1_win_layout[] =
  334. {
  335.      0,  0, 80,  4, /* register window (top rows) */
  336.      0,  5, 24, 17, /* disassembler window (left colums) */
  337.     25,  5, 55,  8, /* memory #1 window (right, upper middle) */
  338.     25, 14, 55,  8, /* memory #2 window (right, lower middle) */
  339.     0,    23, 80,  1, /* command line window (bottom rows) */
  340. };
  341.  
  342. int intern_iot (int *io, int md);
  343. int (*extern_iot) (int *, int) = intern_iot;
  344. int execute_instruction (int md);
  345.  
  346. /* PDP1 Registers */
  347. typedef struct
  348. {
  349.     UINT32 pc;
  350.     int ac;
  351.     int io;
  352.     int y;
  353.     int ib;
  354.     int ov;
  355.     int f;
  356.     int flag[8];
  357.     int sense[8];
  358. }
  359. pdp1_Regs;
  360.  
  361.  
  362. static pdp1_Regs pdp1;
  363.  
  364. #define PC        pdp1.pc
  365. #define AC        pdp1.ac
  366. #define IO        pdp1.io
  367. #define Y        pdp1.y
  368. #define IB        pdp1.ib
  369. #define OV        pdp1.ov
  370. #define F        pdp1.f
  371. #define FLAG    pdp1.flag
  372. #define F1        pdp1.flag[1]
  373. #define F2        pdp1.flag[2]
  374. #define F3        pdp1.flag[3]
  375. #define F4        pdp1.flag[4]
  376. #define F5        pdp1.flag[5]
  377. #define F6        pdp1.flag[6]
  378. #define SENSE   pdp1.sense
  379. #define S1        pdp1.sense[1]
  380. #define S2        pdp1.sense[2]
  381. #define S3        pdp1.sense[3]
  382. #define S4        pdp1.sense[4]
  383. #define S5        pdp1.sense[5]
  384. #define S6        pdp1.sense[6]
  385.  
  386. /* not only 6 flags/senses, but we start counting at 1 */
  387.  
  388. /* public globals */
  389. signed int pdp1_ICount = 50000;
  390.  
  391. /****************************************************************************/
  392. /* Return program counter                                                   */
  393. /****************************************************************************/
  394. unsigned pdp1_get_pc (void)
  395. {
  396.     return PC;
  397. }
  398.  
  399. void pdp1_set_pc (UINT32 newpc)
  400. {
  401.     PC = newpc;
  402. }
  403.  
  404. unsigned pdp1_get_sp (void)
  405. {
  406.     /* nothing to do */
  407.     return 0;
  408. }
  409.  
  410. void pdp1_set_sp (UINT32 newsp)
  411. {
  412.     /* nothing to do */
  413. }
  414.  
  415. void pdp1_set_nmi_line (int state)
  416. {
  417.     /* no NMI line */
  418. }
  419.  
  420. void pdp1_set_irq_line (int irqline, int state)
  421. {
  422.     /* no IRQ line */
  423. }
  424.  
  425. void pdp1_set_irq_callback (int (*callback) (int irqline))
  426. {
  427.     /* no IRQ line */
  428. }
  429.  
  430.  
  431. void pdp1_reset (void *param)
  432. {
  433.     memset (&pdp1, 0, sizeof (pdp1));
  434.     PC = 4;
  435.     SENSE[5] = 1;                       /* for lisp... typewriter input */
  436. }
  437.  
  438. void pdp1_exit (void)
  439. {
  440.     /* nothing to do */
  441. }
  442.  
  443. unsigned pdp1_get_context (void *dst)
  444. {
  445.     if (dst)
  446.         *(pdp1_Regs *) dst = pdp1;
  447.     return sizeof (pdp1_Regs);
  448. }
  449.  
  450. void pdp1_set_context (void *src)
  451. {
  452.     if (src)
  453.         pdp1 = *(pdp1_Regs *) src;
  454. }
  455.  
  456. unsigned pdp1_get_reg (int regnum)
  457. {
  458.     switch (regnum)
  459.     {
  460.     case PDP1_PC: return PC;
  461.     case PDP1_AC: return AC;
  462.     case PDP1_IO: return IO;
  463.     case PDP1_Y:  return Y;
  464.     case PDP1_IB: return IB;
  465.     case PDP1_OV: return OV;
  466.     case PDP1_F:  return F;
  467.     case PDP1_F1: return F1;
  468.     case PDP1_F2: return F2;
  469.     case PDP1_F3: return F3;
  470.     case PDP1_F4: return F4;
  471.     case PDP1_F5: return F5;
  472.     case PDP1_F6: return F6;
  473.     case PDP1_S1: return S1;
  474.     case PDP1_S2: return S2;
  475.     case PDP1_S3: return S3;
  476.     case PDP1_S4: return S4;
  477.     case PDP1_S5: return S5;
  478.     case PDP1_S6: return S6;
  479.     }
  480.     return 0;
  481. }
  482.  
  483. void pdp1_set_reg (int regnum, unsigned val)
  484. {
  485.     switch (regnum)
  486.     {
  487.     case PDP1_PC: PC = val; break;
  488.     case PDP1_AC: AC = val; break;
  489.     case PDP1_IO: IO = val; break;
  490.     case PDP1_Y:  Y  = val; break;
  491.     case PDP1_IB: IB = val; break;
  492.     case PDP1_OV: OV = val; break;
  493.     case PDP1_F:  F  = val; break;
  494.     case PDP1_F1: F1 = val; break;
  495.     case PDP1_F2: F2 = val; break;
  496.     case PDP1_F3: F3 = val; break;
  497.     case PDP1_F4: F4 = val; break;
  498.     case PDP1_F5: F5 = val; break;
  499.     case PDP1_F6: F6 = val; break;
  500.     case PDP1_S1: S1 = val; break;
  501.     case PDP1_S2: S2 = val; break;
  502.     case PDP1_S3: S3 = val; break;
  503.     case PDP1_S4: S4 = val; break;
  504.     case PDP1_S5: S5 = val; break;
  505.     case PDP1_S6: S6 = val; break;
  506.     }
  507. }
  508.  
  509. /* execute instructions on this CPU until icount expires */
  510. int pdp1_execute (int cycles)
  511. {
  512.     int word18;
  513.  
  514.     pdp1_ICount = cycles;
  515.  
  516.     do
  517.     {
  518.  
  519.         CALL_MAME_DEBUG;
  520.  
  521.         word18 = READ_PDP_18BIT (PC++);
  522. /*
  523.         logerror("PC:0%06o ",PC-1);
  524.         logerror("I:0%06o  ",word18);
  525.         logerror("1:%i "    ,FLAG[1]);
  526.         logerror("2:%i "    ,FLAG[2]);
  527.         logerror("3:%i "    ,FLAG[3]);
  528.         logerror("4:%i "    ,FLAG[4]);
  529.         logerror("5:%i "    ,FLAG[5]);
  530.         logerror("6:%i \n"  ,FLAG[6]);
  531. */
  532.         pdp1_ICount -= execute_instruction (word18);
  533.  
  534.     }
  535.     while (pdp1_ICount > 0);
  536.  
  537.     return cycles - pdp1_ICount;
  538. }
  539.  
  540. unsigned pdp1_dasm (char *buffer, unsigned pc)
  541. {
  542. #ifdef MAME_DEBUG
  543.     return dasmpdp1 (buffer, pc);
  544. #else
  545.     sprintf (buffer, "0%06o", READ_PDP_18BIT (pc));
  546.     return 1;
  547. #endif
  548. }
  549.  
  550. static int etime = 0;
  551. INLINE void ea (void)
  552. {
  553.     while (1)
  554.     {
  555.         if (IB == 0)
  556.             return;
  557.  
  558.         etime += 5;
  559.         IB = (READ_PDP_18BIT (Y) >> 12) & 1;
  560.         Y = READ_PDP_18BIT (Y) & 07777;
  561.         if (etime > 100)
  562.         {
  563.             logerror("Massive indirection (>20), assuming emulator fault... bye at:\n");
  564.             logerror("PC:0%06o Y=0%06o\n", PC - 1, Y);
  565.             exit (1);
  566.         }
  567.     }
  568. }
  569.  
  570. /****************************************************************************
  571.  * Return a formatted string for a register
  572.  ****************************************************************************/
  573. const char *pdp1_info (void *context, int regnum)
  574. {
  575.     static char buffer[16][47 + 1];
  576.     static int which = 0;
  577.     pdp1_Regs *r = context;
  578.  
  579.     which = ++which % 16;
  580.     buffer[which][0] = '\0';
  581.     if (!context)
  582.         r = &pdp1;
  583.  
  584.     switch (regnum)
  585.     {
  586.     case CPU_INFO_REG + PDP1_PC: sprintf (buffer[which], "PC:0%06o", r->pc); break;
  587.     case CPU_INFO_REG + PDP1_AC: sprintf (buffer[which], "AC:0%06o", r->ac); break;
  588.     case CPU_INFO_REG + PDP1_IO: sprintf (buffer[which], "IO:0%06o", r->io); break;
  589.     case CPU_INFO_REG + PDP1_Y:  sprintf (buffer[which], "Y :0%06o", r->y);  break;
  590.     case CPU_INFO_REG + PDP1_IB: sprintf (buffer[which], "IB:0%06o", r->ib); break;
  591.     case CPU_INFO_REG + PDP1_OV: sprintf (buffer[which], "OV:0%06o", r->ov); break;
  592.     case CPU_INFO_REG + PDP1_F:  sprintf (buffer[which], "F :0%06o", r->f);  break;
  593.     case CPU_INFO_REG + PDP1_F1: sprintf (buffer[which], "FLAG1:%X", r->flag[1]); break;
  594.     case CPU_INFO_REG + PDP1_F2: sprintf (buffer[which], "FLAG2:%X", r->flag[2]); break;
  595.     case CPU_INFO_REG + PDP1_F3: sprintf (buffer[which], "FLAG3:%X", r->flag[3]); break;
  596.     case CPU_INFO_REG + PDP1_F4: sprintf (buffer[which], "FLAG4:%X", r->flag[4]); break;
  597.     case CPU_INFO_REG + PDP1_F5: sprintf (buffer[which], "FLAG5:%X", r->flag[5]); break;
  598.     case CPU_INFO_REG + PDP1_F6: sprintf (buffer[which], "FLAG6:%X", r->flag[6]); break;
  599.     case CPU_INFO_REG + PDP1_S1: sprintf (buffer[which], "SENSE1:%X", r->sense[1]); break;
  600.     case CPU_INFO_REG + PDP1_S2: sprintf (buffer[which], "SENSE2:%X", r->sense[2]); break;
  601.     case CPU_INFO_REG + PDP1_S3: sprintf (buffer[which], "SENSE3:%X", r->sense[3]); break;
  602.     case CPU_INFO_REG + PDP1_S4: sprintf (buffer[which], "SENSE4:%X", r->sense[4]); break;
  603.     case CPU_INFO_REG + PDP1_S5: sprintf (buffer[which], "SENSE5:%X", r->sense[5]); break;
  604.     case CPU_INFO_REG + PDP1_S6: sprintf (buffer[which], "SENSE6:%X", r->sense[6]); break;
  605.     case CPU_INFO_FLAGS:
  606.         sprintf (buffer[which], "%c%c%c%c%c%c-%c%c%c%c%c%c",
  607.                  r->flag[6] ? '6' : '.',
  608.                  r->flag[5] ? '5' : '.',
  609.                  r->flag[4] ? '4' : '.',
  610.                  r->flag[3] ? '3' : '.',
  611.                  r->flag[2] ? '2' : '.',
  612.                  r->flag[1] ? '1' : '.',
  613.                  r->sense[6] ? '6' : '.',
  614.                  r->sense[5] ? '5' : '.',
  615.                  r->sense[4] ? '4' : '.',
  616.                  r->sense[3] ? '3' : '.',
  617.                  r->sense[2] ? '2' : '.',
  618.                  r->sense[1] ? '1' : '.');
  619.         break;
  620.     case CPU_INFO_NAME: return "PDP1";
  621.     case CPU_INFO_FAMILY: return "DEC PDP-1";
  622.     case CPU_INFO_VERSION: return "1.1";
  623.     case CPU_INFO_FILE: return __FILE__;
  624.     case CPU_INFO_CREDITS: return
  625.             "Brian Silverman (original Java Source)\n"
  626.             "Vadim Gerasimov (original Java Source)\n"
  627.             "Chris Salomon (MESS driver)\n";
  628.     case CPU_INFO_REG_LAYOUT: return (const char *) pdp1_reg_layout;
  629.     case CPU_INFO_WIN_LAYOUT: return (const char *) pdp1_win_layout;
  630.     }
  631.     return buffer[which];
  632. }
  633.  
  634.  
  635. int execute_instruction (int md)
  636. {
  637.     etime = 0;
  638.     Y = md & 07777;
  639.     IB = (md >> 12) & 1;               /* */
  640.     switch (md >> 13)
  641.     {
  642.     case AND:
  643.         ea ();
  644.         AC &= READ_PDP_18BIT (Y);
  645.         etime += 10;
  646.         break;
  647.     case IOR:
  648.         ea ();
  649.         AC |= READ_PDP_18BIT (Y);
  650.         etime += 10;
  651.         break;
  652.     case XOR:
  653.         ea ();
  654.         AC ^= READ_PDP_18BIT (Y);
  655.         etime += 10;
  656.         break;
  657.     case XCT:
  658.         ea ();
  659.         etime += 5 + execute_instruction (READ_PDP_18BIT (Y));
  660.         break;
  661.     case CALJDA:
  662.         {
  663.             int target = (IB == 0) ? 64 : Y;
  664.  
  665.             WRITE_PDP_18BIT (target, AC);
  666.             AC = (OV << 17) + PC;
  667.             PC = target + 1;
  668.             etime += 10;
  669.             break;
  670.         }
  671.     case LAC:
  672.         ea ();
  673.         AC = READ_PDP_18BIT (Y);
  674.         etime += 10;
  675.         break;
  676.     case LIO:
  677.         ea ();
  678.         IO = READ_PDP_18BIT (Y);
  679.         etime += 10;
  680.         break;
  681.     case DAC:
  682.         ea ();
  683.         WRITE_PDP_18BIT (Y, AC);
  684.         etime += 10;
  685.         break;
  686.     case DAP:
  687.         ea ();
  688.         WRITE_PDP_18BIT (Y, (READ_PDP_18BIT (Y) & 0770000) + (AC & 07777));
  689.         etime += 10;
  690.         break;
  691.     case DIO:
  692.         ea ();
  693.         WRITE_PDP_18BIT (Y, IO);
  694.         etime += 10;
  695.         break;
  696.     case DZM:
  697.         ea ();
  698.         WRITE_PDP_18BIT (Y, 0);
  699.         etime += 10;
  700.         break;
  701.     case ADD:
  702.         ea ();
  703.         AC = AC + READ_PDP_18BIT (Y);
  704.         OV = AC >> 18;
  705.         AC = (AC + OV) & 0777777;
  706.         if (AC == 0777777)
  707.             AC = 0;
  708.         etime += 10;
  709.         break;
  710.     case SUB:
  711.         {
  712.             int diffsigns;
  713.  
  714.             ea ();
  715.             diffsigns = ((AC >> 17) ^ (READ_PDP_18BIT (Y) >> 17)) == 1;
  716.             AC = AC + (READ_PDP_18BIT (Y) ^ 0777777);
  717.             AC = (AC + (AC >> 18)) & 0777777;
  718.             if (AC == 0777777)
  719.                 AC = 0;
  720.             if (diffsigns && (READ_PDP_18BIT (Y) >> 17 == AC >> 17))
  721.                 OV = 1;
  722.             etime += 10;
  723.             break;
  724.         }
  725.     case IDX:
  726.         ea ();
  727.         AC = READ_PDP_18BIT (Y) + 1;
  728.         if (AC == 0777777)
  729.             AC = 0;
  730.         WRITE_PDP_18BIT (Y, AC);
  731.         etime += 10;
  732.         break;
  733.     case ISP:
  734.         ea ();
  735.         AC = READ_PDP_18BIT (Y) + 1;
  736.         if (AC == 0777777)
  737.             AC = 0;
  738.         WRITE_PDP_18BIT (Y, AC);
  739.         if ((AC & 0400000) == 0)
  740.             PC++;
  741.         etime += 10;
  742.         break;
  743.     case SAD:
  744.         ea ();
  745.         if (AC != READ_PDP_18BIT (Y))
  746.             PC++;
  747.         etime += 10;
  748.         break;
  749.     case SAS:
  750.         ea ();
  751.         if (AC == READ_PDP_18BIT (Y))
  752.             PC++;
  753.         etime += 10;
  754.         break;
  755.     case MUS:
  756.         ea ();
  757.         if ((IO & 1) == 1)
  758.         {
  759.             AC = AC + READ_PDP_18BIT (Y);
  760.             AC = (AC + (AC >> 18)) & 0777777;
  761.             if (AC == 0777777)
  762.                 AC = 0;
  763.         }
  764.         IO = (IO >> 1 | AC << 17) & 0777777;
  765.         AC >>= 1;
  766.         etime += 10;
  767.         break;
  768.     case DIS:
  769.         {
  770.             int acl;
  771.  
  772.             ea ();
  773.             acl = AC >> 17;
  774.             AC = (AC << 1 | IO >> 17) & 0777777;
  775.             IO = ((IO << 1 | acl) & 0777777) ^ 1;
  776.             if ((IO & 1) == 1)
  777.             {
  778.                 AC = AC + (READ_PDP_18BIT (Y) ^ 0777777);
  779.                 AC = (AC + (AC >> 18)) & 0777777;
  780.             }
  781.             else
  782.             {
  783.                 AC = AC + 1 + READ_PDP_18BIT (Y);
  784.                 AC = (AC + (AC >> 18)) & 0777777;
  785.             }
  786.             if (AC == 0777777)
  787.                 AC = 0;
  788.             etime += 10;
  789.             break;
  790.         }
  791.     case JMP:
  792.         ea ();
  793.         PC = Y;
  794.         etime += 5;
  795.         break;
  796.     case JSP:
  797.         ea ();
  798.         AC = (OV << 17) + PC;
  799.         PC = Y;
  800.         etime += 5;
  801.         break;
  802.     case SKP:
  803.         {
  804.             int cond = (((Y & 0100) == 0100) && (AC == 0)) ||
  805.             (((Y & 0200) == 0200) && (AC >> 17 == 0)) ||
  806.             (((Y & 0400) == 0400) && (AC >> 17 == 1)) ||
  807.             (((Y & 01000) == 01000) && (OV == 0)) ||
  808.             (((Y & 02000) == 02000) && (IO >> 17 == 0)) ||
  809.             (((Y & 7) != 0) && !FLAG[Y & 7]) ||
  810.             (((Y & 070) != 0) && !SENSE[(Y & 070) >> 3]) ||
  811.             ((Y & 070) == 010);
  812.  
  813.             if (IB == 0)
  814.             {
  815.                 if (cond)
  816.                     PC++;
  817.             }
  818.             else
  819.             {
  820.                 if (!cond)
  821.                     PC++;
  822.             }
  823.             if ((Y & 01000) == 01000)
  824.                 OV = 0;
  825.             etime += 5;
  826.             break;
  827.         }
  828.     case SFT:
  829.         {
  830.             int nshift = 0;
  831.             int mask = md & 0777;
  832.  
  833.             while (mask != 0)
  834.             {
  835.                 nshift += mask & 1;
  836.                 mask = mask >> 1;
  837.             }
  838.             switch ((md >> 9) & 017)
  839.             {
  840.                 int i;
  841.  
  842.             case 1:
  843.                 for (i = 0; i < nshift; i++)
  844.                     AC = (AC << 1 | AC >> 17) & 0777777;
  845.                 break;
  846.             case 2:
  847.                 for (i = 0; i < nshift; i++)
  848.                     IO = (IO << 1 | IO >> 17) & 0777777;
  849.                 break;
  850.             case 3:
  851.                 for (i = 0; i < nshift; i++)
  852.                 {
  853.                     int tmp = AC;
  854.  
  855.                     AC = (AC << 1 | IO >> 17) & 0777777;
  856.                     IO = (IO << 1 | tmp >> 17) & 0777777;
  857.                 }
  858.                 break;
  859.             case 5:
  860.                 for (i = 0; i < nshift; i++)
  861.                     AC = ((AC << 1 | AC >> 17) & 0377777) + (AC & 0400000);
  862.                 break;
  863.             case 6:
  864.                 for (i = 0; i < nshift; i++)
  865.                     IO = ((IO << 1 | IO >> 17) & 0377777) + (IO & 0400000);
  866.                 break;
  867.             case 7:
  868.                 for (i = 0; i < nshift; i++)
  869.                 {
  870.                     int tmp = AC;
  871.  
  872.                     AC = ((AC << 1 | IO >> 17) & 0377777) + (AC & 0400000);        /* shouldn't that be IO?, no it is the sign! */
  873.                     IO = (IO << 1 | tmp >> 17) & 0777777;
  874.                 }
  875.                 break;
  876.             case 9:
  877.                 for (i = 0; i < nshift; i++)
  878.                     AC = (AC >> 1 | AC << 17) & 0777777;
  879.                 break;
  880.             case 10:
  881.                 for (i = 0; i < nshift; i++)
  882.                     IO = (IO >> 1 | IO << 17) & 0777777;
  883.                 break;
  884.             case 11:
  885.                 for (i = 0; i < nshift; i++)
  886.                 {
  887.                     int tmp = AC;
  888.  
  889.                     AC = (AC >> 1 | IO << 17) & 0777777;
  890.                     IO = (IO >> 1 | tmp << 17) & 0777777;
  891.                 }
  892.                 break;
  893.             case 13:
  894.                 for (i = 0; i < nshift; i++)
  895.                     AC = (AC >> 1) + (AC & 0400000);
  896.                 break;
  897.             case 14:
  898.                 for (i = 0; i < nshift; i++)
  899.                     IO = (IO >> 1) + (IO & 0400000);
  900.                 break;
  901.             case 15:
  902.                 for (i = 0; i < nshift; i++)
  903.                 {
  904.                     int tmp = AC;
  905.  
  906.                     AC = (AC >> 1) + (AC & 0400000);    /* shouldn't that be IO, no it is the sign */
  907.                     IO = (IO >> 1 | tmp << 17) & 0777777;
  908.                 }
  909.                 break;
  910.             default:
  911.                 logerror("Undefined shift: ");
  912.                 logerror("0%06o at ", md);
  913.                 logerror("0%06o\n", PC - 1);
  914.                 exit (1);
  915.             }
  916.             etime += 5;
  917.             break;
  918.         }
  919.     case LAW:
  920.         AC = (IB == 0) ? Y : Y ^ 0777777;
  921.         etime += 5;
  922.         break;
  923.     case IOT:
  924.         etime += extern_iot (&IO, md);
  925.         break;
  926.     case OPR:
  927.         {
  928.             int nflag;
  929.             int state;
  930.             int i;
  931.  
  932.             etime += 5;
  933.             if ((Y & 0200) == 0200)
  934.                 AC = 0;
  935.             if ((Y & 04000) == 04000)
  936.                 IO = 0;
  937.             if ((Y & 01000) == 01000)
  938.                 AC ^= 0777777;
  939.             if ((Y & 0400) == 0400)
  940.             {
  941.                 /* ignored till I emulate the extention switches... with
  942.                  * continue...
  943.                  */
  944.                 logerror("PDP1 Program executed HALT: at ");
  945.                 logerror("0%06o\n", PC - 1);
  946.                 logerror("HALT ignored...\n");
  947.                 /* exit(1); */
  948.             }
  949.             nflag = Y & 7;
  950.             if (nflag < 1)               /* was 2 */
  951.                 break;
  952.             state = (Y & 010) == 010;
  953.             if (nflag == 7)
  954.             {
  955.                 for (i = 1; i < 7; i++)        /* was 2 */
  956.                 {
  957.                     FLAG[i] = state;
  958.                 }
  959.                 break;
  960.             }
  961.             FLAG[nflag] = state;
  962.             F = 0;
  963.             for (i = 1; i < 7; i++)
  964.             {
  965.                 F += (1 << (i - 1)) * (FLAG[i] != 0);
  966.             }
  967.             break;
  968.         }
  969.     default:
  970.         logerror("Undefined instruction: ");
  971.         logerror("0%06o at ", md);
  972.         logerror("0%06o\n", PC - 1);
  973.         exit (1);
  974.     }
  975.     return etime;
  976. }
  977.  
  978. int intern_iot (int *iio, int md)
  979. {
  980.     logerror("No external IOT function given (IO=0%06o) -> EXIT(1) invoked in PDP1\\PDP1.C\n", *iio);
  981.     exit (1);
  982. }
  983.